/*
 * Copyright (C) 2020 Agrui
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include "ParameterCheck.h"
#include "OSMemory.h"
#include "IpcService.h"
#include "IpcMgrService.h"
#include "IpcMgrServiceDispatcher.h"
#include "IpcServiceManager.h"

typedef struct {
    int serviceId;
    int subId;
} BindClientDataInfo;


IPC_RESULT ipcMgrServiceHandleAllocClient(IpcTransaction* transaction, void* clientData, int msg, void* data, int dataLen) {
    PARAMTER_CHECK_RETURN_VALUE(transaction, IPC_RESULT_INVALID_PARAMETER);
    IpcService* service = SERVICE_FROM_TRANSACTION(transaction);
    BindClientDataInfo* bindClient = (BindClientDataInfo*)data;
    int serviceId = bindClient->serviceId;
    int subId = bindClient->subId;
    IpcServiceManager* mgr = getDefaultIpcServiceManager();
    if (msg) {
        return IPC_RESULT_ERROR;
    }

    int8_t clientId = allocClient(mgr, transaction->channelId, serviceId, subId);
    if (clientId == -1) {
        return IPC_RESULT_EXCEED_MAX_CLIENT;
    }

    sendIpcResponse(transaction, IPC_RESULT_OK, &clientId, sizeof(clientId));
    return IPC_RESULT_OK;
}

IPC_RESULT ipcMgrServiceHandleRemoveClient(IpcTransaction* transaction, void* clientData, int msg, void* data, int dataLen) {
    PARAMTER_CHECK_RETURN_VALUE(transaction, IPC_RESULT_INVALID_PARAMETER);
    IpcService* service = SERVICE_FROM_TRANSACTION(transaction);
    int8_t serviceId = *(int8_t*)data;

    IpcServiceManager* mgr = getDefaultIpcServiceManager();
    if (msg) {
        return IPC_RESULT_ERROR;
    }

    removeClient(mgr, transaction->channelId, serviceId, transaction->clientId);
    sendIpcResponse(transaction, IPC_RESULT_OK, NULL, 0);
    return IPC_RESULT_OK;
}

IpcService* newIpcMgrService() {
    IpcService* service = newIpcService(IPC_SERVICE_MGR, NULL, NULL);
    registerDispatchTable(service, mgrServiceDispatchTable, ARRAY_SIZE(mgrServiceDispatchTable));
    return service;
}

